home *** CD-ROM | disk | FTP | other *** search
- #include <Types.h> // include prototype
- #include <stdArg.h> // include prototype
-
- #include "debug.h"
-
- Boolean TrapAvailable(unsigned short);
-
-
-
- // argument types passed
- #define kSHORT_ARG 1 // argument is a short
- #define kLONG_ARG 2 // argument is a long
- #define kINT_ARG 3 // argument is an int
- #define kCHAR_ARG 4 // argument is a char
- #define kSTRING_ARG 5 // argument is a C string
- #define kPSTRING_ARG 6 // argument is a Pascal string
- #define kUknown_ARG -1 // unknown argument type
- #define kMAX_LEN 255 // maximum output length
-
- // format control tokens
- #define kFORMAT_TOKEN '%' // start of format sequence
- #define kLEADINGZERO_TOKEN '.' // start leading zeros token
- #define kLEFTJUSTIFY_TOKEN '-' // left justify token
- #define kPLUS_TOKEN '+' // positive sign output token
- #define kSPACE_TOKEN ' ' // space for sign output token
- #define kNULL_TOKEN 0x00 // null token end of input
-
- // format modifier tokens
- #define kUP_LONG_TOK 'L' // long modifier
- #define kLOW_LONG_TOK 'l' // "
- #define kUP_SHORT_TOK 'H' // short modifier
- #define kLOW_SHORT_TOK 'h' // "
- #define kUP_DEC_TOK 'D' // signed decimal modifier
- #define kLOW_DEC_TOK 'd' // "
- #define kUP_UNS_TOK 'U' // unsigned decimal modifier
- #define kLOW_UNS_TOK 'u' // "
- #define kUP_HEX_TOK 'X' // hex modifier
- #define kLOW_HEX_TOK 'x' // "
- #define kUP_OCT_TOK 'O' // octal modifier
- #define kLOW_OCT_TOK 'o' // "
- #define kUP_CHAR_TOK 'C' // char modifier
- #define kLOW_CHAR_TOK 'c' // "
- #define kUP_STR_TOK 'S' // C string modifier
- #define kLOW_STR_TOK 's' // "
- #define kUP_PSTR_TOK 'P' // Pascal string modifier
- #define kLOW_PSTR_TOK 'p' // "
- #define kUP_BIN_TOK 'B' // Binnary modifier
- #define kLOW_BIN_TOK 'b' // "
-
- // char constants
- #define kSpace_CHAR ' ' // ASCII value of a space
- #define kZero_CHAR '0' // ASCII value of zero
- #define kNine_CHAR '9' // ASCII value of nine
- #define kHexTEN_UP_CHAR 'A' // ASCII value to represent Hex ten Upper case
- #define kHexTEN_LO_CHAR 'a' // ASCII value to represent Hex ten Lowwer case
- #define kUndefined_CHAR '#' // ASCII value to output for an undefined format
- #define kMINUS_CHAR '-' // ASCII value to show negative number
- #define kPLUS_CHAR '+' // ASCII value to show positive number
-
- // numeric constants
- #define kBinary_BASE 2 // binary equals base two
- #define kOctal_BASE 8 // octal equals base eight
- #define kDecmal_BASE 10 // decimal equals base ten
- #define kHex_BASE 16 // hex equals base sixteen
- #define kNumDecDigits ((9 - 0)+1) // number of numeric decimal digits
- #define kBYTE_MASK 0xFF // mask for a byte value
- #define kBITS_PER_BYTE 0x08 // number of bits in a byte
-
- // internal function to convert a 32 bit number to any base with format control
- static short numtobase(long numin, unsigned short base, char* str,
- short zpaddlen, short spacepaddlen, short argtype, char ten_char,
- Boolean usesign, Boolean useplus, Boolean usespace, Boolean leftjustify);
-
- // internal function to parse a numeric value
- static char* parse_numeric_value(char* pbuffer, short *value);
-
- // internal function to look at the next token
- static char Peek_Token(char* pbuffer);
-
- // internal function to poop the next token
- static char * Get_Next_Token(char* pbuffer, char* token);
-
- // internal function to output a char into a buffer
- static char* Output_Char(char* pbuffer, char token, short * length);
-
- /*-----------------------------------------------------------------------
- * void MyDebugStr(char * pbuffer, ...)
- * PURPOSE:
- * drop into debugger with formater string
- *
- * In: pbuffer - pointer to debug format string NULL TERMINATED
- *
- *
- * format commands
- * % - start format sequence
- * - - left justify
- * + - use sign
- ' ' - use space for plus and a minus for negative
- * n - min field width
- * .m - min leading zero's
- * L - long modifier
- *
- * %[-][n][.m][L]B - display binnary number
- * %[-][n][.m][L]O - display octal number
- * %[-][n][.m][L]X - display hex number
- * %[-][+][n][.m][L]D - display decimal number
- * %[-][n][.m][L]U - display unsigned number
- * %[-][n]S - display C string
- * %[-][n]P - display a Pascal string
- * %[-][n]C - display a charactor
- * %% - display %
- *
- * args - format arguments MUST MATCH commands!!!
- *
- *
- *----------------------------------------------------------------------*/
- void Debug(char* pbuffer, ...)
- {
- va_list next_Arg; // next argument to process
- char poutput[kMAX_LEN + 1]; // output buffer
- char *ptemp; // temp string pointer
- char *poutptr; // current output pointer
- char *p; // string argument pointer
- long num; // number to convert
- short plen; // length of string pointer
- short zpaddlen; // leading zero
- short spacepaddlen; // leading space padd length
- short strlength; // string length
- short length; // num bytes in output buffer
- short argtype; // type of argument passed
- unsigned short base; // base of output number
- char ch; // char argument
- char token; // current token
- char token_peek; // next token
- char ten_char; // either 'A' or 'a'
- Boolean usesign; // number is a signed numeric value
- Boolean useplus; // use a plus sign if positive
- Boolean usespace; // use a space if positive
- Boolean leftjustify; // use left justification
-
- va_start(next_Arg, pbuffer); // start the var args
-
- zpaddlen = 0; // init zero padd
- spacepaddlen = 0; // init space padd
-
- length = 0; // init length
- poutptr = poutput+1; // init output pointer (byte 0 is length byte)
- do { // process format string until end of input
- // or max output length is reached
- pbuffer = Get_Next_Token(pbuffer, &token); // get the current token
-
- switch (token) { // key off of current token
-
- case kFORMAT_TOKEN: // start of format sequence
- token_peek = Peek_Token(pbuffer); // look at next token
-
- if (token_peek) { // check for end of input
-
- if (token_peek == kFORMAT_TOKEN) { // check for sequence %%
- pbuffer = Get_Next_Token(pbuffer, &token);
- // output a %
- poutptr = Output_Char(poutptr, kFORMAT_TOKEN, &length);
- break; // done with this sequence
- }
-
- leftjustify = false; // init left justify to false
- usesign = false; // init to unsigned output
- useplus = false; // dont force sign to be outputed
- usespace = false; // dont force sign spaceing to be outputed
- argtype = kUknown_ARG; // init argumnent type
-
- if (token_peek == kLEFTJUSTIFY_TOKEN) { // check for sequence %-
- // get the token
- pbuffer = Get_Next_Token(pbuffer, &token);
- token_peek = Peek_Token(pbuffer); // look at next token
- leftjustify = true; // turn on left justify
- }
-
- if (token_peek == kPLUS_TOKEN) { // check for sequence %+
- // get the token
- pbuffer = Get_Next_Token(pbuffer, &token);
- token_peek = Peek_Token(pbuffer); // look at next token
- useplus = true; // turn on plus sign
- }
- else {
- if (token_peek == kSPACE_TOKEN) { // check for sequence %' '
- // get the token
- pbuffer = Get_Next_Token(pbuffer, &token);
- token_peek = Peek_Token(pbuffer); // look at next token
- usespace = true; // turn on space for sign
- }
- }
- // check for specified leading space
- // field width
- if ((token_peek >= kZero_CHAR) && (token_peek <= kNine_CHAR)) {
- pbuffer = parse_numeric_value(pbuffer, &spacepaddlen);
- token_peek = Peek_Token(pbuffer); // look at next token
- }
- if (token_peek == kLEADINGZERO_TOKEN) { // check for start of leading zero sequence
- pbuffer = Get_Next_Token(pbuffer, &token);
- token_peek = Peek_Token(pbuffer); // look at next token
- // parse leading zero length
- if ((token_peek >= kZero_CHAR) && (token_peek <= kNine_CHAR)) {
- pbuffer = parse_numeric_value(pbuffer, &zpaddlen);
- token_peek = Peek_Token(pbuffer); // look at next token
- }
- }
-
- if (! (token_peek)) { // check for end of buffer
- break;
- }
-
- argtype = kINT_ARG; // default to int argument
- if ((token_peek == kUP_LONG_TOK) || (token_peek == kLOW_LONG_TOK)) {
- argtype = kLONG_ARG; // long modifier
- pbuffer = Get_Next_Token(pbuffer, &token);
- token_peek = Peek_Token(pbuffer); // look at next token
- }
- else {
- if ((token_peek == kUP_SHORT_TOK) || (token_peek == kLOW_SHORT_TOK)) {
- argtype = kSHORT_ARG; // short modifier
- pbuffer = Get_Next_Token(pbuffer, &token);
- token_peek = Peek_Token(pbuffer); // look at next token
- }
-
- }
- if (!token_peek) { // check for end of buffer
- break;
- }
- switch (token_peek) { // key off token
- case kUP_DEC_TOK:
- case kLOW_DEC_TOK: // signed decimal number
- base = kDecmal_BASE; // set base to 10
- usesign = true; // and use sign
- break;
-
- case kUP_UNS_TOK:
- case kLOW_UNS_TOK: // unsigned decimal number
- base = kDecmal_BASE; // set base to 10
- usesign = false; // do not use sign
- break;
-
- case kUP_HEX_TOK:
- base = kHex_BASE; // set base to 16
- usesign = false; // do not use sign
- ten_char = kHexTEN_UP_CHAR; // lowwer case hex
- break;
-
- case kLOW_HEX_TOK: // hex number
- base = kHex_BASE; // set base to 16
- usesign = false; // do not use sign
- ten_char = kHexTEN_LO_CHAR; // lowwer case hex
- break;
-
- case kUP_OCT_TOK:
- case kLOW_OCT_TOK: // octal number
- base = kOctal_BASE; // set base to 8
- usesign = false; // do not use sign
- break;
-
- case kUP_BIN_TOK:
- case kLOW_BIN_TOK: // binnary number
- base = kBinary_BASE; // set base to 2
- usesign = false; // do not use sign
- break;
-
- case kUP_CHAR_TOK:
- case kLOW_CHAR_TOK: // char
- argtype = kCHAR_ARG; // set argtype to char
- break;
- case kUP_STR_TOK:
- case kLOW_STR_TOK: // C string
- argtype = kSTRING_ARG; // set argtype to C string
- break;
-
- case kUP_PSTR_TOK:
- case kLOW_PSTR_TOK: // Pascal string
- argtype = kPSTRING_ARG; // set argtype to Pascal string
- break;
-
- default: // invalid token (should never get here)
- // output a char to show invalid
- poutptr = Output_Char(poutptr, kUndefined_CHAR, &length);
- break;
- } // end format control sequence
-
- pbuffer = Get_Next_Token(pbuffer, &token); // pop token off the stack
-
- switch (argtype) { // key of argument type to process
-
- case kINT_ARG: // argument is a int value
- // get next short argument
- num = (long)(va_arg(next_Arg,int));
- // format the number
- strlength = numtobase(num, base, poutptr, zpaddlen,
- spacepaddlen, argtype, ten_char, usesign,
- useplus, usespace, leftjustify);
- poutptr += strlength; // increment output buffer
- length += strlength; // increment output length
- break;
-
- case kSHORT_ARG: // argument is a short value
- // get next short argument
- num = (long)(va_arg(next_Arg,short));
- // format the number
- strlength = numtobase(num, base, poutptr, zpaddlen,
- spacepaddlen, argtype, ten_char, usesign,
- useplus, usespace, leftjustify);
- poutptr += strlength; // increment output buffer
- length += strlength; // increment output length
- break;
-
- case kLONG_ARG: // argument is a long value
- num = va_arg(next_Arg,long); // get the next long argument
- // format the number
- strlength = numtobase(num, base, poutptr, zpaddlen,
- spacepaddlen, argtype, ten_char, usesign,
- useplus, usespace, leftjustify);
- poutptr += strlength; // increment output buffer
- length += strlength; // increment output length
- break;
-
- case kCHAR_ARG: // argument is a char
- // note: char is put on stack as a short!
- ch = va_arg(next_Arg,short); // get the char argument
- spacepaddlen --; // decrement leading space by 1
- // (since char output size equals one)
- if (leftjustify == false) { // if right justified
- for (; spacepaddlen > 0; ) { // ouput spaces
- poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
- spacepaddlen--; // decrement counter
- }
- } // ouput the char
- poutptr = Output_Char(poutptr, ch, &length);
- if (leftjustify) { // if left justfication
- for (; spacepaddlen > 0; ) { // output spaces
- poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
- spacepaddlen--; // decrement counter
- }
- }
- break;
-
- case kSTRING_ARG: // argument is a string
- p = (char*)va_arg(next_Arg,long); // get string pointer argument
- ptemp = p; // assign a temp pointer
- for (strlength = 0; *ptemp; *ptemp++) {
- strlength++; // calculate the length of the string
- }
-
- if (leftjustify == false) { // if right justify
- // output leading spaces
- for (; strlength < spacepaddlen; ) {
- poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
- spacepaddlen--; // decrement counter
- }
- }
- for (; *p ;) { // output the string
- // one char at a time
- poutptr = Output_Char(poutptr, *p++, &length);
- } // until end null char
-
- if (leftjustify) { // if left justify
- // output trailing spaces
- for (; strlength < spacepaddlen; ) {
- poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
- spacepaddlen--; // decrement counter
- }
- }
- break;
-
- case kPSTRING_ARG: // argument is a Pascal string
- p = (char*)va_arg(next_Arg,long); // get the string pointer argument
- strlength = *p++; // get length and increment pointer
-
- if (leftjustify == false) { // if right justify
- // output leading spaces
- for (; strlength < spacepaddlen; ) {
- poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
- spacepaddlen--; // decrement count
- }
- }
- // output the string
- for (plen = strlength; plen ; plen--) {
- poutptr = Output_Char(poutptr, *p++, &length);
- }
- if (leftjustify) { // if right justify
- // padd with trailing spaces
- for (; strlength < spacepaddlen; ) {
- poutptr = Output_Char(poutptr, kSpace_CHAR, &length);
- spacepaddlen--; // decrement buffer
- }
- }
- break;
- }
- }
- break;
-
- case kNULL_TOKEN: // null token
- break; // this is the end of input
-
- default: // normal char
- poutptr = Output_Char(poutptr, token, &length); // output the char
- break;
- } // end token switch
- } while ((token) && (length < kMAX_LEN)); // end process input
- // when at end of string
- // or ouput buffer is full
- *poutput = (char)length; // get the length byte
- // ParamText((StringPtr)poutput, nil, nil,nil);
-
- va_end(next_Arg); // done processing arguments
-
- // Alert(1000, nil);
- DebugStr((unsigned char*)poutput);
- }
-
-
- /*-----------------------------------------------------------------------
- * char* parse_numeric_value(char* pbuffer, short *value)
- *
- * PURPOSE:
- * parse a numeric from input buffer and assign to (*value)
- *
- * char* pbuffer: IN input buffer to parse
- * short* value: IN/OUT numeric parsed value
- *
- * RETURN
- * current position of buffer
- *
- *----------------------------------------------------------------------*/
- static char* parse_numeric_value(char* pbuffer, short *value)
- {
- short mulfactor; // multiplication factor
-
- for (*value = 0, mulfactor = 1; // get 1 digit at a time
- ((*pbuffer >= kZero_CHAR) && (*pbuffer <= kNine_CHAR));
- *pbuffer++, mulfactor *= kNumDecDigits ) {
- (*value) *= (mulfactor); // multiply by 10 * digit number
- (*value) += (*pbuffer - kZero_CHAR); // assign least significant digit
- if ((*value) > kMAX_LEN) { // check for max length
- (*value) = kMAX_LEN; // assign max length
- }
- }
- return pbuffer; // return current buffer pointer
- }
-
-
- /*-----------------------------------------------------------------------
- * static char Peek_Token(char* pbuffer)
- *
- * PURPOSE:
- * look at next token to process
- * This was done just for code readability
- *
- * char* pbuffer: IN input buffer to parse
- *
- * RETURN
- * next token
- *
- *----------------------------------------------------------------------*/
- static char Peek_Token(char* pbuffer)
- {
- return (*pbuffer); // return current token
- }
-
- /*-----------------------------------------------------------------------
- * static char * Get_Next_Token(char* pbuffer, char* token)
- *
- * PURPOSE:
- * look at next token to process
- * This was done primaraly for code readability
- *
- * char* pbuffer: IN input buffer to parse
- * char* token IN/OUT where to place the token
- *
- * RETURN
- * new buffer position
- *
- *----------------------------------------------------------------------*/
- static char * Get_Next_Token(char* pbuffer, char* token)
- {
- *token = *pbuffer++; // assign value
- // and increment buffer
- return pbuffer; // return new buffer position
- }
-
- /*-----------------------------------------------------------------------
- * static char* Output_Char(char* pbuffer, char token, short * length)
- *
- * PURPOSE:
- * Output a token into the output buffer
- *
- * char* pbuffer: IN/OUT output buffer
- * char token IN token to output
- * short* length IN/OUT incremented by 1
- *
- * RETURN
- * new buffer position
- *
- *----------------------------------------------------------------------*/
- static char* Output_Char(char* pbuffer, char token, short * length)
- {
- *pbuffer++ = token; // put token in buffer
- // and increment buffer
- (*length)++; // increment length
- return pbuffer; // return new buffer position
- }
-
- /*-----------------------------------------------------------------------
- * short numtobase(long numin, unsigned short base, char* str, short zpaddlen,
- * short zpaddlen, short spacepaddlen, short argtype, char ten_char,
- * Boolean usesign, Boolean forcesign, Boolean showspace, Boolean leftjustify)
- *
- * PURPOSE:
- * Convert a number to any base with leading spaces and zero's left or right justfied
- *
- * long numin: IN number to convert.
- * unsigned short base: IN base to convert to (Must be kBinary_BASE or greater).
- * char* str: IN/OUT Output string.
- * short zpaddlen: IN max zero padding
- * short spacepaddlen: IN max space padding
- * short argtype: IN kSHORT_ARG or kLONG_ARG or INT_ARG
- * char ten_char IN char to represent 10 hex
- * Boolean usesign: IN use is a signed number
- * Boolean showplus: IN display plus if positive display minus if negative
- * Boolean showspace: IN display space if positive display minus if negative
- * Boolean leftjustify: IN left justfy the output
- *
- * RETURN
- * length of output
- *
- *----------------------------------------------------------------------*/
-
- static short numtobase(long numin, unsigned short base, char* str,
- short zpaddlen, short spacepaddlen, short argtype, char ten_char,
- Boolean usesign, Boolean showplus, Boolean showspace, Boolean leftjustify)
- {
- unsigned long num; // unsigned version of number passed
- char *s; // current position in buffer
- char *p1; // temp pointer to output
- char *p2; // temp pointer to output
- short len; // length of output
- short count; // counter for spaces
- short numspaces; // number of spaces to output
- short argsize; // number of bytes of numin
- char temp; // temp char for byte swaping
- Boolean negative; // negative number flag
-
- negative = false; // default to positive number
-
- if (base < kBinary_BASE) { // base must be at least two
- return 0; // return zero length output
- }
- if (usesign) { // check sign flag
- if (numin < 0) { // check for negative number
- numin = -numin; // get absolute value of number
- negative = true; // set negative flag
- }
- }
- // determine the number of bytes of numin
- switch (argtype) { // case off argument type
- case kSHORT_ARG: // arg is short
- argsize = sizeof(short); // let compilier figure it out
- break;
-
- case kLONG_ARG: // arg is a long
- argsize = sizeof(long); // let compilier figure it out
- break;
-
- case kINT_ARG: // arg is init
- argsize = sizeof(int); // let compilier figure it out
- break;
-
- default: // unknown argument
- return 0; // return no output
- }
- // we must do this for short values
- for (num = 0, count = 0; argsize; argsize--, count++){ // loop to assign num to numin
- num |= numin & ((unsigned long)kBYTE_MASK) << // Mask off
- (count * kBITS_PER_BYTE);
- // one byte at a time
- }
-
- s = str; // set current position
- len = 0; // init length to zero
- // OUTPUT STRING WILL BE REVERSED!
- do { // loop to convert num into base
- *s = (num % base) + kZero_CHAR; // get next digit
- if (*s > kNine_CHAR) { // check for greater than nine
- // set output so 'A' or 'a' represents ten
- *s = ((num % base) + ten_char) - kNumDecDigits;
- }
- s++; // increment pointer for next char
- len ++; // increment output length
- } while ((num /= base) > 0); // end when number is zero
-
- // AT THIS POINT NUMBER IS REVERSED!
-
- while (len < zpaddlen) { // check for leading zero padd
- *s++ = kZero_CHAR; // output zero
- len ++; // increment length
- }
- if (usesign) { // check sign flag
- if (negative) { // check for negative number
- *s++ = kMINUS_CHAR; // output '-'
- len ++; // increment length
- }
- else { // number is positive
- if (showspace) { // check to ouput space for sign
- *s++ = kSpace_CHAR; // output ' '
- len ++; // increment length
- }
- else { // dont show space
- if (showplus) { // check to output '+'
- *s++ = kPLUS_CHAR; // output '+'
- len ++; // incrment length
- }
- }
- }
- }
- if (leftjustify == false) { // check for right justify
- while (len < spacepaddlen) { // add leading spaces
- *s++ = kSpace_CHAR; // output next space
- len ++; // incremnt output length
- }
- }
- else { // left justify!
- // to left justify
- // the array needs to be shifted down
- // and spaces added to the begining
- // since number is reversed
- count = spacepaddlen - len; // number of spaces to shift
- if (count > 0) { // must be at least one
- numspaces = len; // number of bytes in array
- for (p1 = (s + (count -1 )), p2 = s -1; numspaces--; p1--, p2--) {
- *p1 = *p2; // shift next byte
- }
- s += count; // increment current position
- for (; count-- ;) { // loop to add spaces
- *p1-- = kSpace_CHAR; // output a space
- len++; // increment output length
- }
- }
- }
- *s = 0; // null terminate C string
- // ouput string must now be
- // reversed for final output
- for (p1 = str, p2 = (--s); p1 < p2; p1++, p2--) { // reverse loop
- temp = *p1; // swap
- *p1 = *p2; // *p1
- *p2 = temp; // with *p2
- }
- return len; // return length of output
- }
-
- Boolean TrapAvailable(unsigned short PatchTrap)
- {
- return (NGetTrapAddress(PatchTrap, (PatchTrap & 0x0800) ? ToolTrap : OSTrap)) !=
- (NGetTrapAddress(_Unimplemented, (_Unimplemented & 0x0800) ? ToolTrap : OSTrap));
- }
-